package com.zslibrary.StateHandle;

import android.os.SystemClock;
import android.util.SparseArray;

import com.zslibrary.Enum.StateDefine;
import com.zslibrary.Enum.StateEventDefine;
import com.zslibrary.Tools.ZSLog;

import java.util.LinkedList;
import java.util.Queue;

public class StateMachine {
    private SparseArray<StateHandle> mHandleMap=new SparseArray<>();
    private @StateDefine.State int mCurrentState=StateDefine.STATE_IDLE;
    private Queue<Integer> mEventList=new LinkedList<>();
    private int mPause=0;
    private @StateEventDefine.StateEvent int mPauseEvent=StateEventDefine.EVT_NONE;
    private @StateEventDefine.StateEvent int currentEvent=StateEventDefine.EVT_NONE;

    public void registerState(@StateDefine.State int state,StateHandle handle){
        mHandleMap.put(state,handle);
    }

    public void startStateMachine(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                while(true){
                    stateEngine();
                    SystemClock.sleep(200);
                }
            }
        }).start();
    }

    private void postEvent(@StateEventDefine.StateEvent int event){
        mEventList.offer(event);
    }

    private void stateEngine(){
        StateHandle currentHandle=mHandleMap.get(mCurrentState);
        int event=currentHandle.handle();
        postEvent(event);
        currentEvent=this.selectEvent();
        if(mPause==1) {   //收到暂停
            ZSLog.d("ready to pause");
            mPause = 2;   //可以暂停
        }
        while(mPause==2){   //等待暂停释放
            mPauseEvent=currentEvent;
            SystemClock.sleep(10);
        }
        mCurrentState=currentHandle.getNextHop(currentEvent);
    }

    protected  @StateEventDefine.StateEvent int selectEvent(){
        int selectedEvent=StateEventDefine.EVT_NONE;
        for(@StateEventDefine.StateEvent int event:mEventList){
            if(event==StateEventDefine.EVT_DISCONNECT){
                selectedEvent=event;
                break;
            }
            if(event==StateEventDefine.EVT_RECONNECT){
                selectedEvent=event;
                break;
            }
            if(event==StateEventDefine.EVT_RESET){
                selectedEvent=event;
                continue;
            }
            if(event==StateEventDefine.EVT_EXECUTE){
                if(selectedEvent!=StateEventDefine.EVT_RESET)
                    selectedEvent=event;
                continue;
            }
            if(event==StateEventDefine.EVT_QUERY_GATE){
                if(selectedEvent==StateEventDefine.EVT_NONE)
                    selectedEvent=event;
                continue;
            }
        }
        mEventList.clear();
        return selectedEvent;
    }

    public @StateEventDefine.StateEvent int pauseStateMachine(){
        mPause=1;   //准备暂停
        ZSLog.d("prepare to pause");
        do{
            SystemClock.sleep(10);
        }while(mPause!=2);  //等待执行完，暂停
        ZSLog.d("pausing");
        return mPauseEvent;
    }

    public void resumeStateMachine(@StateEventDefine.StateEvent int event){
        ZSLog.d("resume state machine");
        mPause=0;   //释放阻塞
        currentEvent=event; //更新事件
    }

    public @StateDefine.State int getCurrentState(){
        if(mPause==2)
            return StateDefine.STATE_PAUSE;
        return mCurrentState;
    }
}
